package com.wu.http.server;


import com.wu.javax.servlet.http.Cookie;
import com.wu.javax.servlet.http.HttpServletResponse;
import com.wu.util.TomcatUtil;

import java.io.*;
import java.util.Map;

import static com.wu.constant.Constant.SESSION_ID;


public class MyHttpServletResponse implements HttpServletResponse {
    private final OutputStream oos;
    private final MyHttpServletRequest request;
    private String contentType;
    private final Cookie[] cookies = new Cookie[50];
    private int cookieIndex = 0;

    public MyHttpServletResponse(MyHttpServletRequest request, OutputStream oos) {
        this.oos = oos;
        this.request = request;
        Cookie cookie = new Cookie(SESSION_ID, request.getSessionId());
        this.cookies[this.cookieIndex] = cookie;
        this.cookieIndex++;
    }

    /**
     * 1、从request中取出uri
     * 2、判断是否在本地存在这个uri指代的文件 没有, 404
     * 3、有 以输入流读取这个文件
     * 4、以输出流将文件写到客户端,要加入响应的协议.
     */
    @Override
    public void sendRedirect() {
        // 响应协议头
        String responseProtocol;
        // 响应的内容
        byte[] fileContent;
        //请求资源的地址
        String uri = request.getRequestURI();
        //请求的文件
        File file = new File(request.getRealPath(), uri);
        if (!file.exists()) {
            fileContent = readFile(new File(request.getRealPath(), "/404.html"));
            responseProtocol = gen404(fileContent.length);
        } else {
            fileContent = readFile(file);
            responseProtocol = gen200(fileContent.length);
        }
        try {
            // 写协议
            oos.write(responseProtocol.getBytes());
            oos.flush();
            // 写出文件
            oos.write(fileContent);
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void addCookie(Cookie cookie) {
        if (cookieIndex >= cookies.length) {
            return;
        }
        cookies[cookieIndex++] = cookie;
    }

    @Override
    public Cookie[] getCookies() {
        Cookie[] cookie = new Cookie[cookieIndex];
        System.arraycopy(cookies, 0, cookie, 0, cookieIndex);
        return cookie;
    }

    @Override
    public MyWriter getMyWriter() {
        return new MyWriter(this.oos, this);
    }

    private byte[] readFile(File file) {
        FileInputStream fis = null;
        //字节数组输出流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            // 读取这个文件
            fis = new FileInputStream(file);
            byte[] bs = new byte[1024];
            int length;
            while ((length = fis.read(bs, 0, bs.length)) != -1) {
                // 写到内存缓存
                byteArrayOutputStream.write(bs, 0, length);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 一次性地从内存中读取所有的字节数组返回
        return byteArrayOutputStream.toByteArray();
    }

    /**
     * 要考虑静态文件的类型
     *
     * @param bodyLength , 内容的长度
     * @return
     */
    private String gen200(long bodyLength) {
        // 文件的后缀名
        String fileExtension = TomcatUtil.getFileExtension(this.request.getRequestURI());
        String protocol200 = null;
        Map<String, String> mappingMap = Main.getMappingMap();
        for (Map.Entry<String, String> mappingEntry : mappingMap.entrySet()) {
            String extension = mappingEntry.getKey();
            if (extension.equalsIgnoreCase(fileExtension)) {
                contentType = mappingEntry.getValue();
                protocol200 = "HTTP/1.1 200 OK\r\nContent-Type: " + contentType + "\r\nContent-Length: " + bodyLength + "\r\n\r\n";
                break;
            }
        }
        return protocol200;
    }

    /**
     * 产生404响应
     *
     * @return
     */
    private String gen404(long bodyLength) {
        return "HTTP/1.1 404 File Not Found\r\nContent-Type: text/html\r\nContent-Length: "
                + bodyLength + "\r\n\r\n";
    }

    @Override
    public PrintWriter getWriter() {
        return new PrintWriter(this.oos);
    }

    @Override
    public String getContentType() {
        return this.contentType;
    }

}
